#ifndef E6B04D16_A1A2_40F4_BC83_79290DD59D11
#define E6B04D16_A1A2_40F4_BC83_79290DD59D11

#include "equation.hpp"
#include "method.hpp"

const double golden_pizo = 1.618034;

static double golden_ration_function(Equation const &eq, double a, double b,
                                     double accuracy) {
  double x1 = b - (b - a) / golden_pizo;
  double x2 = a + (b - a) / golden_pizo;
  double y1 = eq.get_equation()(x1);
  double y2 = eq.get_equation()(x2);

  while (true) {
    if (y1 >= y2) {
      a = x1;
      x1 = x2;
      y1 = y2;
      x2 = a + (b - a) / golden_pizo;
      y2 = eq.get_equation()(x2);
    } else {
      b = x2;
      x2 = x1;
      y2 = y1;
      x1 = b - (b - a) / golden_pizo;
      y1 = eq.get_equation()(x1);
    }
    if (std::abs(b - a) < accuracy)
      return (a + b) / 2;
  }
}

class GoldenRationMethod
    : public Method<
          std::function<double(Equation const &, double, double, double)>> {
public:
  GoldenRationMethod()
      : Method(golden_ration_function, "Метод золотого сечения") {}
  double solve(Equation const &eq, double a, double b,
               double accuracy) const override {
    return get_solver()(eq, a, b, accuracy);
  }
};

#endif /* E6B04D16_A1A2_40F4_BC83_79290DD59D11 */
